#ifndef _SCULL_COMMON_H
#define _SCULL_COMMON_H

#include <linux/types.h>
#include <linux/cdev.h>

// Major devno, 0 means dynamic alloc
#define SCULL_MAJOR 0
// Start minor devno
#define SCULL_MINOR 0
// Scull device count
#define SCULL_COUNT 4

// Default scull qset array size
#define SCULL_QSET 1000
// Default scull quantum size
#define SCULL_QUANTUM 4000

extern char *scull_name;
extern int scull_major;
extern int scull_minor;
extern int scull_dev_nr;

struct scull_qset {
	void **data;
	struct scull_qset *next;
};

struct scull_dev {
	struct cdev cdev;
	struct kobject *kobj;
	struct scull_qset *data;
	// The current quantum size
	int quantum_size;
	// The current qset array size
	int qset_size;
	// The data length;
	ulong length;
	struct semaphore sem;
};

int scull_trim(struct scull_dev *dev);
struct scull_qset *scull_qset_alloc(int quantum);
int scull_open(struct inode *inode, struct file *filp);
ssize_t scull_read(struct file *filp, char __user *buf, size_t size, loff_t *offset);
ssize_t scull_write(struct file *filp, const char __user *buf, size_t size, loff_t *offset);
loff_t scull_llseek(struct file *filp, loff_t offset, int whence);
int scull_setup_cdev(struct scull_dev *dev, int index, const struct file_operations *fops);
void scull_delete_cdev(struct scull_dev *dev, int index);

#endif // _SCULL_COMMON_H